#include "oled.h"
#include "string.h"
#include "stdio.h"
#include "math.h"

// 修正的字库（6x8 ASCII字符）- 只包含常用字符
const uint8_t Font6x8[95][6] = {
    {0x00,0x00,0x00,0x00,0x00,0x00}, // 空格 (0x20)
    {0x00,0x00,0x5F,0x00,0x00,0x00}, // ! (0x21)
    {0x00,0x07,0x00,0x07,0x00,0x00}, // " (0x22)
    {0x14,0x7F,0x14,0x7F,0x14,0x00}, // # (0x23)
    {0x24,0x2A,0x7F,0x2A,0x12,0x00}, // $ (0x24)
    {0x23,0x13,0x08,0x64,0x62,0x00}, // % (0x25)
    {0x36,0x49,0x55,0x22,0x50,0x00}, // & (0x26)
    {0x00,0x05,0x03,0x00,0x00,0x00}, // ' (0x27)
    {0x00,0x1C,0x22,0x41,0x00,0x00}, // ( (0x28)
    {0x00,0x41,0x22,0x1C,0x00,0x00}, // ) (0x29)
    {0x14,0x08,0x3E,0x08,0x14,0x00}, // * (0x2A)
    {0x08,0x08,0x3E,0x08,0x08,0x00}, // + (0x2B)
    {0x00,0x50,0x30,0x00,0x00,0x00}, // , (0x2C)
    {0x08,0x08,0x08,0x08,0x08,0x00}, // - (0x2D)
    {0x00,0x60,0x60,0x00,0x00,0x00}, // . (0x2E)
    {0x20,0x10,0x08,0x04,0x02,0x00}, // / (0x2F)
    {0x3E,0x51,0x49,0x45,0x3E,0x00}, // 0 (0x30)
    {0x00,0x42,0x7F,0x40,0x00,0x00}, // 1 (0x31)
    {0x42,0x61,0x51,0x49,0x46,0x00}, // 2 (0x32)
    {0x21,0x41,0x45,0x4B,0x31,0x00}, // 3 (0x33)
    {0x18,0x14,0x12,0x7F,0x10,0x00}, // 4 (0x34)
    {0x27,0x45,0x45,0x45,0x39,0x00}, // 5 (0x35)
    {0x3C,0x4A,0x49,0x49,0x30,0x00}, // 6 (0x36)
    {0x01,0x71,0x09,0x05,0x03,0x00}, // 7 (0x37)
    {0x36,0x49,0x49,0x49,0x36,0x00}, // 8 (0x38)
    {0x06,0x49,0x49,0x29,0x1E,0x00}, // 9 (0x39)
    {0x00,0x36,0x36,0x00,0x00,0x00}, // : (0x3A)
    {0x00,0x56,0x36,0x00,0x00,0x00}, // ; (0x3B)
    {0x08,0x14,0x22,0x41,0x00,0x00}, // < (0x3C)
    {0x14,0x14,0x14,0x14,0x14,0x00}, // = (0x3D)
    {0x00,0x41,0x22,0x14,0x08,0x00}, // > (0x3E)
    {0x02,0x01,0x51,0x09,0x06,0x00}, // ? (0x3F)
    {0x32,0x49,0x79,0x41,0x3E,0x00}, // @ (0x40)
    {0x7E,0x11,0x11,0x11,0x7E,0x00}, // A (0x41)
    {0x7F,0x49,0x49,0x49,0x36,0x00}, // B (0x42)
    {0x3E,0x41,0x41,0x41,0x22,0x00}, // C (0x43)
    {0x7F,0x41,0x41,0x22,0x1C,0x00}, // D (0x44)
    {0x7F,0x49,0x49,0x49,0x41,0x00}, // E (0x45)
    {0x7F,0x09,0x09,0x09,0x01,0x00}, // F (0x46)
    {0x3E,0x41,0x49,0x49,0x7A,0x00}, // G (0x47)
    {0x7F,0x08,0x08,0x08,0x7F,0x00}, // H (0x48)
    {0x00,0x41,0x7F,0x41,0x00,0x00}, // I (0x49)
    {0x20,0x40,0x41,0x3F,0x01,0x00}, // J (0x4A)
    {0x7F,0x08,0x14,0x22,0x41,0x00}, // K (0x4B)
    {0x7F,0x40,0x40,0x40,0x40,0x00}, // L (0x4C)
    {0x7F,0x02,0x0C,0x02,0x7F,0x00}, // M (0x4D)
    {0x7F,0x04,0x08,0x10,0x7F,0x00}, // N (0x4E)
    {0x3E,0x41,0x41,0x41,0x3E,0x00}, // O (0x4F)
    {0x7F,0x09,0x09,0x09,0x06,0x00}, // P (0x50)
    {0x3E,0x41,0x51,0x21,0x5E,0x00}, // Q (0x51)
    {0x7F,0x09,0x19,0x29,0x46,0x00}, // R (0x52)
    {0x46,0x49,0x49,0x49,0x31,0x00}, // S (0x53)
    {0x01,0x01,0x7F,0x01,0x01,0x00}, // T (0x54)
    {0x3F,0x40,0x40,0x40,0x3F,0x00}, // U (0x55)
    {0x1F,0x20,0x40,0x20,0x1F,0x00}, // V (0x56)
    {0x3F,0x40,0x38,0x40,0x3F,0x00}, // W (0x57)
    {0x63,0x14,0x08,0x14,0x63,0x00}, // X (0x58)
    {0x07,0x08,0x70,0x08,0x07,0x00}, // Y (0x59)
    {0x61,0x51,0x49,0x45,0x43,0x00}, // Z (0x5A)
    {0x00,0x7F,0x41,0x41,0x00,0x00}, // [ (0x5B)
    {0x02,0x04,0x08,0x10,0x20,0x00}, // \ (0x5C)
    {0x00,0x41,0x41,0x7F,0x00,0x00}, // ] (0x5D)
    {0x04,0x02,0x01,0x02,0x04,0x00}, // ^ (0x5E)
    {0x40,0x40,0x40,0x40,0x40,0x00}, // _ (0x5F)
    {0x00,0x01,0x02,0x04,0x00,0x00}, // ` (0x60)
    {0x20,0x54,0x54,0x54,0x78,0x00}, // a (0x61)
    {0x7F,0x48,0x44,0x44,0x38,0x00}, // b (0x62)
    {0x38,0x44,0x44,0x44,0x20,0x00}, // c (0x63)
    {0x38,0x44,0x44,0x48,0x7F,0x00}, // d (0x64)
    {0x38,0x54,0x54,0x54,0x18,0x00}, // e (0x65)
    {0x08,0x7E,0x09,0x01,0x02,0x00}, // f (0x66)
    {0x0C,0x52,0x52,0x52,0x3E,0x00}, // g (0x67)
    {0x7F,0x08,0x04,0x04,0x78,0x00}, // h (0x68)
    {0x00,0x44,0x7D,0x40,0x00,0x00}, // i (0x69)
    {0x20,0x40,0x44,0x3D,0x00,0x00}, // j (0x6A)
    {0x7F,0x10,0x28,0x44,0x00,0x00}, // k (0x6B)
    {0x00,0x41,0x7F,0x40,0x00,0x00}, // l (0x6C)
    {0x7C,0x04,0x18,0x04,0x78,0x00}, // m (0x6D)
    {0x7C,0x08,0x04,0x04,0x78,0x00}, // n (0x6E)
    {0x38,0x44,0x44,0x44,0x38,0x00}, // o (0x6F)
    {0x7C,0x14,0x14,0x14,0x08,0x00}, // p (0x70)
    {0x08,0x14,0x14,0x18,0x7C,0x00}, // q (0x71)
    {0x7C,0x08,0x04,0x04,0x08,0x00}, // r (0x72)
    {0x48,0x54,0x54,0x54,0x20,0x00}, // s (0x73)
    {0x04,0x3F,0x44,0x40,0x20,0x00}, // t (0x74)
    {0x3C,0x40,0x40,0x20,0x7C,0x00}, // u (0x75)
    {0x1C,0x20,0x40,0x20,0x1C,0x00}, // v (0x76)
    {0x3C,0x40,0x30,0x40,0x3C,0x00}, // w (0x77)
    {0x44,0x28,0x10,0x28,0x44,0x00}, // x (0x78)
    {0x0C,0x50,0x50,0x50,0x3C,0x00}, // y (0x79)
    {0x44,0x64,0x54,0x4C,0x44,0x00}, // z (0x7A)
    {0x00,0x08,0x36,0x41,0x00,0x00}, // { (0x7B)
    {0x00,0x00,0x7F,0x00,0x00,0x00}, // | (0x7C)
    {0x00,0x41,0x36,0x08,0x00,0x00}, // } (0x7D)
    {0x08,0x04,0x08,0x10,0x08,0x00}, // ~ (0x7E)
};

// OLED写命令
// OLED写命令
void OLED_WriteCommand(uint8_t cmd)
{
    HAL_I2C_Mem_Write(&OLED_I2C, OLED_ADDRESS, 0x00, 1, &cmd, 1, 1000);
}

// OLED写数据
// OLED写数据
void OLED_WriteData(uint8_t data)
{
    HAL_I2C_Mem_Write(&OLED_I2C, OLED_ADDRESS, 0x40, 1, &data, 1, 1000);
}

// OLED初始化 - 使用更稳定的初始化序列
void OLED_Init(void)
{
    HAL_Delay(100); // 等待OLED上电稳定
    
    OLED_WriteCommand(0xAE); // 关闭显示
    
    // 基础显示设置
    OLED_WriteCommand(0x20); // 设置内存地址模式
    OLED_WriteCommand(0x00); // 水平地址模式
    
    OLED_WriteCommand(0xB0); // 设置页起始地址
    OLED_WriteCommand(0xC8); // 设置扫描方向(从下到上)
    
    // 列地址设置
    OLED_WriteCommand(0x00); // 设置低列地址
    OLED_WriteCommand(0x10); // 设置高列地址
    
    OLED_WriteCommand(0x40); // 设置显示起始行
    
    // 对比度设置
    OLED_WriteCommand(0x81); // 设置对比度
    OLED_WriteCommand(0x7F); // 对比度值(0-255)
    
    // 段重映射
    OLED_WriteCommand(0xA1); // 设置段重映射(0xA0正常, 0xA1翻转)
    
    // 显示模式
    OLED_WriteCommand(0xA6); // 设置正常显示(0xA6正常, 0xA7反色)
    
    // 多路复用比率
    OLED_WriteCommand(0xA8); // 设置多路复用比率
    OLED_WriteCommand(0x3F); // 1/64 duty
    
    OLED_WriteCommand(0xA4); // 整个显示开启(跟随RAM内容)
    
    // 显示偏移
    OLED_WriteCommand(0xD3); // 设置显示偏移
    OLED_WriteCommand(0x00); // 无偏移
    
    // 振荡器频率
    OLED_WriteCommand(0xD5); // 设置显示时钟分频比/振荡器频率
    OLED_WriteCommand(0x80); // 设置分频比
    
    // 预充电周期
    OLED_WriteCommand(0xD9); // 设置预充电周期
    OLED_WriteCommand(0xF1); 
    
    // COM引脚配置
    OLED_WriteCommand(0xDA); // 设置COM引脚硬件配置
    OLED_WriteCommand(0x12); 
    
    // VCOMH设置
    OLED_WriteCommand(0xDB); // 设置VCOMH
    OLED_WriteCommand(0x40); 
    
    // 充电泵设置
    OLED_WriteCommand(0x8D); // 设置充电泵
    OLED_WriteCommand(0x14); // 启用充电泵
    
    OLED_WriteCommand(0xAF); // 开启显示
    
    HAL_Delay(100);
    OLED_Clear(); // 清屏确保显示正常
}

// 清屏
void OLED_Clear(void)
{
    for(uint8_t page = 0; page < 8; page++) {
        OLED_WriteCommand(0xB0 + page); // 设置页地址
        OLED_WriteCommand(0x00);        // 设置低列地址
        OLED_WriteCommand(0x10);        // 设置高列地址
        
        for(uint8_t col = 0; col < 128; col++) {
            OLED_WriteData(0x00);       // 清除所有像素
        }
    }
}

// 设置光标位置
void OLED_SetCursor(uint8_t x, uint8_t y)
{
    if(x > 127) x = 127;
    if(y > 7) y = 7;
    
    OLED_WriteCommand(0xB0 + y);        // 设置页地址
    OLED_WriteCommand(((x & 0xF0) >> 4) | 0x10); // 设置高列地址
    OLED_WriteCommand((x & 0x0F) | 0x01);        // 设置低列地址
}

// 显示字符
void OLED_ShowChar(uint8_t x, uint8_t y, char chr)
{
    // 只处理可打印ASCII字符(0x20-0x7E)
    if(chr < 0x20 || chr > 0x7E) {
        chr = ' '; // 不可打印字符显示为空格
    }
    
    uint8_t c = chr - 0x20; // 计算字库索引
    
    OLED_SetCursor(x, y);
    for(uint8_t i = 0; i < 6; i++) {
        OLED_WriteData(Font6x8[c][i]);
    }
}

// 显示字符串
void OLED_ShowString(uint8_t x, uint8_t y, char *str)
{
    uint8_t x_pos = x;
    while(*str) {
        OLED_ShowChar(x_pos, y, *str++);
        x_pos += 6;
        if(x_pos > 122) { // 换行检查
            x_pos = 0;
            y++;
            if(y > 7) y = 7;
        }
    }
}

// 显示数字
void OLED_ShowNumber(uint8_t x, uint8_t y, int32_t num)
{
    char buffer[12];
    sprintf(buffer, "%ld", num);
    OLED_ShowString(x, y, buffer);
}

void OLED_ShowHexNumber(uint8_t x, uint8_t y, int32_t num)
{
    char buffer[12];
    sprintf(buffer, "0x%lx", num);
    OLED_ShowString(x, y, buffer);
}

// 显示16进制数组
void OLED_ShowHexArray(uint8_t x, uint8_t y, const uint8_t *data, uint8_t len)
{
    // 缓冲区：每个字节2字符 + 结束符
    char buffer[len * 2 + 1];
    char *ptr = buffer;
    
    for(uint8_t i = 0; i < len; i++) {
        ptr += sprintf(ptr, "%02X", data[i]);
    }
    OLED_ShowString(x, y, buffer);
}

// 修正的浮点数显示函数
void OLED_ShowFloat(uint8_t x, uint8_t y, float num, uint8_t decimal_places)
{
    int32_t integer_part, decimal_part;
    float temp;
    
    // 处理负数
    if (num < 0) {
        OLED_ShowChar(x, y, '-');
        x += 6;
        num = -num;
    }
    
    // 分离整数和小数部分
    integer_part = (int32_t)num;
    temp = num - integer_part;
    
    // 计算小数部分
    for (uint8_t i = 0; i < decimal_places; i++) {
        temp *= 10;
    }
    decimal_part = (int32_t)(temp + 0.5); // 四舍五入
    
    // 显示整数部分
    char int_buffer[10];
    sprintf(int_buffer, "%ld", integer_part);
    OLED_ShowString(x, y, int_buffer);
    x += strlen(int_buffer) * 6;
    
    // 显示小数点
    OLED_ShowChar(x, y, '.');
    x += 6;
    
    // 显示小数部分
    char dec_buffer[10];
    sprintf(dec_buffer, "%0*ld", decimal_places, decimal_part);
    
    // 确保小数位数正确
    uint8_t len = strlen(dec_buffer);
    if (len > decimal_places) {
        // 如果小数部分位数超过指定位数，取后几位
        OLED_ShowString(x, y, dec_buffer + (len - decimal_places));
    } else {
        OLED_ShowString(x, y, dec_buffer);
    }
}

// 新增：简单的浮点数显示（使用sprintf，需要启用浮点数支持）
void OLED_ShowFloatSimple(uint8_t x, uint8_t y, float num, uint8_t decimal_places)
{
    char buffer[16];
    char format[8];
    
    // 创建格式字符串，如 "%.1f", "%.2f" 等
    sprintf(format, "%%.%df", decimal_places);
    sprintf(buffer, format, num);
    OLED_ShowString(x, y, buffer);
}